/**
* @project admin-go-api
* @name sysRole
* @descriptions 角色数据层
* @author 寒锋
* @date 2023-12-20 10:31:35
 */

package dao

import (
	"admin-go-api/api/entity"
	"admin-go-api/common/util"
	. "admin-go-api/pkg/db"
	"time"
)

// GetSysRoleByName 根据角色名称获取角色信息
func GetSysRoleByName(name string, roleId uint) (sysRole entity.SysRole) {
	model := Db.Where("role_name = ?", name)
	if roleId != 0 {
		model = model.Where("role_id <> ?", roleId)
	}
	model.First(&sysRole)
	return sysRole
}

// GetSysRoleByKey 根据角色key获取角色信息
func GetSysRoleByKey(roleKey string, roleId uint) (sysRole entity.SysRole) {
	model := Db.Where("role_key = ?", roleKey)
	if roleId != 0 {
		model = model.Where("role_id <> ?", roleId)
	}
	model.First(&sysRole)
	return sysRole
}

// GetSysRoleById 根据角色id获取角色信息
func GetSysRoleById(roleId int) (sysRole entity.SysRole) {
	Db.First(&sysRole, roleId)
	return sysRole
}

// CreateSysRole 添加角色
func CreateSysRole(sysRole entity.StoreSysRoleDto) bool {
	data := entity.SysRole{
		RoleName:    sysRole.RoleName,
		RoleKey:     sysRole.RoleKey,
		Status:      sysRole.Status,
		Description: sysRole.Description,
		CreateTime:  util.HTime{Time: time.Now()},
	}
	result := Db.Create(&data)
	if result.RowsAffected > 0 {
		return true
	}
	return false
}

// UpdateSysRole 更新角色
func UpdateSysRole(sysRole entity.UpdateSysRoleDto) bool {
	data := entity.SysRole{
		RoleName: sysRole.RoleName,
		RoleKey:  sysRole.RoleKey,
		Status:   sysRole.Status,
	}
	if sysRole.Description != "" {
		data.Description = sysRole.Description
	}
	result := Db.Where("role_id = ?", sysRole.RoleId).Updates(&data)
	return result.Error == nil
}

// DeleteSysRole 删除角色
func DeleteSysRole(dto entity.SysRoleIdDto) error {
	// 启动事务
	tx := Db.Begin()
	if err := tx.Error; err != nil {
		return err
	}
	if err := tx.Table("sys_role").Where("role_id = ?", dto.RoleId).Delete(&entity.SysRole{}).Error; err != nil {
		tx.Rollback()
		return err
	}
	if err := tx.Table("sys_role_menu").Where("role_id = ?", dto.RoleId).Delete(&entity.SysRoleMenu{}).Error; err != nil {
		tx.Rollback()
		return err
	}
	return tx.Commit().Error
}

// UpdateSysRoleState 更新角色状态
func UpdateSysRoleState(dto entity.UpdateSysRoleStateDto) bool {
	data := entity.SysRole{
		Status: dto.Status,
	}
	result := Db.Where("role_id = ?", dto.RoleId).Updates(&data)
	if result.RowsAffected > 0 {
		return true
	}
	return false
}

// GetSysRoleList 分页获取角色列表
func GetSysRoleList(PageNum int, PageSize int, RoleName string, RoleKey string, Status int, BeginTime string, EndTime string) (sysRole []*entity.SysRole, count int64) {
	model := Db.Table("sys_role")
	if RoleName != "" {
		model = model.Where("role_name = ?", RoleName)
	}
	if RoleKey != "" {
		model = model.Where("role_key = ?", RoleKey)
	}
	if Status != 0 {
		model = model.Where("status = ?", Status)
	}
	if BeginTime != "" && EndTime != "" {
		model = model.Where("create_time between ? and ?", BeginTime, EndTime)
	}
	model.Count(&count)
	model.Limit(PageSize).Offset((PageNum - 1) * PageSize).Order("create_time desc").Find(&sysRole)
	return sysRole, count
}

// QuerySysRoleVoList 角色下拉列表
func QuerySysRoleVoList() (sysRole []entity.SysRoleVo) {
	Db.Table("sys_role").Select("role_id,role_name").Find(&sysRole)
	return sysRole
}

// QueryRoleMenuIdList 根据角色id获取菜单数据id
func QueryRoleMenuIdList(roleId int) (menuIds []entity.SysMenuIdDto) {
	Db.Table("sys_menu sm").
		Select("sm.menu_id").
		Joins("left join sys_role_menu srm on srm.menu_id = sm.menu_id").
		Joins("left join sys_role sr on sr.role_id = srm.role_id").
		Where("sm.menu_type = ?", entity.TypeBtn).
		Where("sr.role_id = ?", roleId).
		Scan(&menuIds)
	return menuIds
}

// AssignPermissions 分配权限
func AssignPermissions(roleMenu entity.RoleMenu) (err error) {
	err = Db.Table("sys_role_menu").Where("role_id = ?", roleMenu.RoleId).Delete(&entity.SysRoleMenu{}).Error
	if err != nil {
		return err
	}
	RoleMenuData := make([]entity.SysRoleMenu, len(roleMenu.MenuIds))
	for index, value := range roleMenu.MenuIds {
		RoleMenuData[index] = entity.SysRoleMenu{
			RoleId: roleMenu.RoleId,
			MenuId: value,
		}
	}
	result := Db.Create(&RoleMenuData)
	return result.Error
}
